package controller;

import model.*;

import java.util.ArrayList;
import java.util.List;

public class Status {
	List<Instruction> instructionList;
	List<Memory> memoryList;
	List<Buffer> loadBuffer;
	List<Buffer> storeBuffer;
	List<ReservationStation> addReservationStation;
	List<ReservationStation> multReservationStation;
	List<FloatRegister> floatRegisterList;
	List<IntegerRegister> integerRegisterList;
	boolean isAdderBusy;
	boolean isMulterBusy;
	boolean isLoadBusy;
	boolean isStorBusy;
	int loadBufferHead;
	int storeBufferHead;
	
	public Status() {
		instructionList = new ArrayList<Instruction>();
		memoryList = new ArrayList<Memory>();
		loadBuffer = new ArrayList<Buffer>();
		storeBuffer = new ArrayList<Buffer>();
		addReservationStation = new ArrayList<ReservationStation>();
		multReservationStation = new ArrayList<ReservationStation>();
		floatRegisterList = new ArrayList<FloatRegister>();
		integerRegisterList = new ArrayList<IntegerRegister>();
		isAdderBusy = false;
		isMulterBusy = false;
		isLoadBusy = false;
		isStorBusy =false;
		loadBufferHead = 0;
		storeBufferHead = 0;
		
		for (int i = 0; i < 1024; ++i) {
			Memory memory = new Memory();
			memory.address = i * 4;
			memoryList.add(memory);
		}
		for (int i = 0; i < 3; ++i) {
			Buffer buffer = new Buffer();
			buffer.name = Control.LOAD + i;
			loadBuffer.add(buffer);
			buffer = new Buffer();
			buffer.name = Control.STOR + i;
			storeBuffer.add(buffer);
		}
		for (int i = 0; i < 3; ++i) {
			ReservationStation rs = new ReservationStation();
			rs.name = Control.ADD + i;
			addReservationStation.add(rs);
		}
		for (int i = 0; i < 2; ++i) {
			ReservationStation rs = new ReservationStation();
			rs.name = Control.MULT + i;
			multReservationStation.add(rs);
		}
		for (int i = 0; i< 11; ++i) {
			FloatRegister fg = new FloatRegister();
			fg.flag  = Control.READY;
			floatRegisterList.add(fg);
			integerRegisterList.add(new IntegerRegister());
		}
	}
	
	ReservationStation getFreeAddRS() {
		for (ReservationStation rs : addReservationStation)
			if (rs.isBusy == false)
				return rs;
		return null;
	}
	ReservationStation getFreeMultRS() {
		for (ReservationStation rs : multReservationStation)
			if (rs.isBusy == false)
				return rs;
		return null;
	}
	Buffer getFreeLoadBuffer() {
		Buffer buffer = null;
		for (int i = loadBufferHead; i < loadBufferHead + 3; ++i) {
			buffer = loadBuffer.get(i % 3);
			if (buffer.isBusy == false)
				return buffer;
		}
		return null;
	}
	Buffer getFreeStoreBuffer() {
		Buffer buffer = null;
		for (int i = storeBufferHead; i < storeBufferHead + 3; ++i) {
			buffer = storeBuffer.get(i % 3);
			if (buffer.isBusy == false)
				return buffer;
		}
		return null;
	}
	
	/*void updateBufferList(String type) {
		if (type.equals(Control.LOAD)) {
			loadBuffer.remove(0);
			loadBuffer.add(new Buffer());
			for (int i = 0; i < 3; ++i)
				loadBuffer.get(i).name = Control.LOAD + i;
		} else {
			storeBuffer.remove(0);
			storeBuffer.add(new Buffer());
			for (int i = 0; i < 3; ++i)
				storeBuffer.get(i).name = Control.STOR + i;
		}
		
	}*/
	
	void printRS() {
		for (ReservationStation rs : addReservationStation) {
			System.out.println(rs.vi + " " + rs.vk + " " + rs.qi + " " + rs.qk);
		}
		
		for (ReservationStation rs : multReservationStation) {
			System.out.println(rs.vi + " " + rs.vk + " " + rs.qi + " " + rs.qk);
		}
	}
	
}
